package flex.cc.order.manage.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import flex.cc.PublicUtil;
import flex.cc.base.dto.LoginAuthDto;
import flex.cc.basicinformation.dao.ChannelDataDao;
import flex.cc.basicinformation.service.ChannelService;
import flex.cc.core.utils.RequestUtil;
import flex.cc.fenfa.dto.RuleCountEntity;
import flex.cc.fenfa.dto.ServicerCountEntity;
import flex.cc.fenfa.service.RuleCountService;
import flex.cc.fenfa.service.ServicerCountService;
import flex.cc.order.manage.dao.OrderCustomerDao;
import flex.cc.order.manage.dao.OrderMainDao;
import flex.cc.order.manage.dao.OrderPolicyDao;
import flex.cc.order.manage.dao.OrderRescueDao;
import flex.cc.order.manage.dao.OrderServiceProviderDao;
import flex.cc.order.manage.dao.OrderTrackDao;
import flex.cc.order.manage.dto.order.OrderCustomerEntity;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderPolicyEntity;
import flex.cc.order.manage.dto.order.OrderRescueEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.vehicle_svr.service.InputService;

/**
 * 
 * @author WANGCONG
 * 2021年11月11日上午10:25:31
 * @desc 服务单下发异步接口
 */
@Service
public class AsyncAllotOrderService {

	private static final Logger logger = LoggerFactory.getLogger(AsyncAllotOrderService.class);
	
	@Autowired
    private OrderMainDao orderMainDao;
    @Autowired
    private OrderCustomerDao orderCustomerDao;
    @Autowired
    private OrderPolicyDao orderPolicyDao;
    @Autowired
    private OrderRescueDao orderRescueDao;
    @Autowired
    private OrderTrackDao orderTrackDao;
    @Autowired
    private InputService inputService;
    @Resource
	private ChannelService channelService;
    @Resource
	private ChannelDataDao channelDataDao;
    @Autowired
    private OrderServiceProviderDao orderServiceProviderDao;
    @Autowired
    private RuleCountService ruleCountService;
    @Autowired
    private ServicerCountService servicerCountService;
    
    /**
     * 
     * @author WANGCONG
     * 2021年11月11日上午10:28:16
     * @desc 异步下单
     */
	@Async
	public void asyncAllotOrder(String dataId, String allot_rescue_url, String servicerId, String publicKey, String servicerName,
			String fenfaCode, String ruleId) {
		logger.info("手工单保存，异步下单==>> 地址:{}", allot_rescue_url);
		Map<String, Object> params = new HashMap<>();
        params.put("dataId", dataId);
        Map<String, Object> requestBodyMap = new HashMap<String, Object>();
        OrderMainEntity orderMainEntity = orderMainDao.getOneByParams(params);
        String result = "";
        if (orderMainEntity != null){
            Map<String, Object> info = new HashMap<>();
            info.put("orderNo", orderMainEntity.getOrderNo());
            OrderCustomerEntity orderCustomerEntity = orderCustomerDao.getOneByParams(info);
            OrderPolicyEntity orderPolicyEntity = orderPolicyDao.getOneByParams(info);
            OrderRescueEntity orderRescueEntity = orderRescueDao.getOneByParams(info);
            OrderTrackEntity orderTrackEntity = orderTrackDao.getOneByParams(info);
            if (PublicUtil.isNotEmpty(orderMainEntity)){
                requestBodyMap.put("orderNo", orderMainEntity.getOrderNo());
                requestBodyMap.put("ownerOrderNo", orderMainEntity.getOwnerOrderNo());
                requestBodyMap.put("incidentType", PublicUtil.isNotEmpty(orderMainEntity.getIncidentType()) ? orderMainEntity.getIncidentType() : 0); // 可以取实际值，为空的默认非事故
                //requestBodyMap.put("incidentType", 0); // TODO 联调默认事故类型为非事故
                requestBodyMap.put("serviceType", orderMainEntity.getServiceItem());
            }
            if (PublicUtil.isNotEmpty(orderTrackEntity)){
                requestBodyMap.put("serviceContent", orderTrackEntity.getTrackDesc());
            }
            if (PublicUtil.isNotEmpty(orderCustomerEntity)){
                requestBodyMap.put("reporterName", orderCustomerEntity.getUsername());
                requestBodyMap.put("reporterPhone", orderCustomerEntity.getMobile());
                requestBodyMap.put("reporterIdNo", orderCustomerEntity.getIdCard());
            }
            if(PublicUtil.isNotEmpty(orderPolicyEntity)){
                requestBodyMap.put("vehicleNo", orderPolicyEntity.getCarNo());
                requestBodyMap.put("vehicleType", orderPolicyEntity.getCarModel());
                requestBodyMap.put("vin", orderPolicyEntity.getCarVin());
            }
            if (PublicUtil.isNotEmpty(orderRescueEntity)){
                requestBodyMap.put("caseProvince", orderRescueEntity.getAddrProvince());
                requestBodyMap.put("caseCity", orderRescueEntity.getAddrCity());
                requestBodyMap.put("caseCounty", orderRescueEntity.getAddrCounty());
                requestBodyMap.put("caseLocation", orderRescueEntity.getAddrAddress());
                requestBodyMap.put("caseLongitude", orderRescueEntity.getAddrLongitude());
                requestBodyMap.put("caseLatitude", orderRescueEntity.getAddrLatitude());
                requestBodyMap.put("desState", orderRescueEntity.getDesProvince());
                requestBodyMap.put("desCity", orderRescueEntity.getDesCity());
                requestBodyMap.put("desCounty", orderRescueEntity.getDesCounty());
                requestBodyMap.put("desAddress", orderRescueEntity.getDesAddress());
                requestBodyMap.put("desLongitude", orderRescueEntity.getDesLongitude());
                requestBodyMap.put("desLatitude", orderRescueEntity.getDesLatitude());
                requestBodyMap.put("dragEnvironment", orderRescueEntity.getEnv());
            }
            //result = "{\"resultCode\":\"0\",\"message\":\"成功\"}";
            //result = inputService.allotRescue(allot_rescue_url, publicKey, requestBodyMap);
            AtomicReference<Integer> counter = new AtomicReference<Integer>(0);
            String temp_code = ""; //记录接口回写的code码，便于轨迹备注插入
            while(counter.get()<3){
            	result = inputService.allotRescue(allot_rescue_url, publicKey, requestBodyMap);
            	if (result != null) {
            		try {
            			JSONObject resultObj = JSONObject.parseObject(result);
            			// 0：正常；非0都为异常；异常超时增加9999状态码
                        String resultCode = PublicUtil.isNotEmpty(resultObj.get("resultCode")) ? resultObj.get("resultCode").toString() : null; 
                        temp_code = resultCode;
                        if(PublicUtil.isNotEmpty(resultCode) && "9999".equals(resultCode)){
                        	counter.compareAndSet(counter.get(), counter.get()+1);
                        }else{
                        	counter.getAndSet(5);
                        }
					} catch (Exception e) {
						counter.getAndSet(5);
					}
            	}else {
            		counter.compareAndSet(counter.get(), counter.get()+1);
            	}
            }
            if("0".equals(temp_code)){//成功
            	saveTrack(orderMainEntity.getOrderNo(), "00", "调用下游下单成功", "01", new Date(), RequestUtil.getLoginUser());
            	//根据返回的信息，插入或更新统计表数据，（更新记录规则轮询数）
            	if("888".equals(fenfaCode)){
            		//此处为手工单选择了救援商，或者是车牌号在最近下过单，直接给原来的救援商，不计入分发规则
            	}else{
            		if("01".equals(fenfaCode)){ //规则匹配到的，新增or更新t_rule_count数据
                    	//1.更新ruleId的数据count+1 //2.更新ruleId、servicerId的server_count+1，时间变更为当前时间
                    	int maxCount = ruleCountService.findMaxCountByRuleId(ruleId);
                    	if(maxCount==0){//说明此规则还没派发过，或者修改规则后，未派发过
            				RuleCountEntity vo_temp = new RuleCountEntity();
            				vo_temp.setDataId(UUID.randomUUID().toString().replace("-", ""));
            				vo_temp.setRuleId(ruleId);
            				vo_temp.setServicerId(servicerId);
            				vo_temp.setServerCount(1);
            				vo_temp.setCount(1);
            				vo_temp.setVersion(0);
            				vo_temp.setCreateTime(new Date());
            				ruleCountService.insertVo(vo_temp);
                    	}else{
                    		Map<String,String> fenfa_param = new HashMap<>();
                        	fenfa_param.put("ruleId", ruleId);
                        	fenfa_param.put("servicerId", servicerId);
                        	RuleCountEntity ruleCountVo =  ruleCountService.queryOneByParam(fenfa_param);
                        	if(ruleCountVo==null){//说明当前服务商未派发过，或者修改规则后，未派发过
                				RuleCountEntity vo = new RuleCountEntity();
                				vo.setDataId(UUID.randomUUID().toString().replace("-", ""));
                				vo.setRuleId(ruleId);
                				vo.setServicerId(servicerId);
                				vo.setServerCount(1);
                				vo.setCount(maxCount);
                				vo.setVersion(0);
                				vo.setCreateTime(new Date());
                				ruleCountService.insertVo(vo);
                			}else{//更新操作
                				ruleCountVo.setServerCount(ruleCountVo.getServerCount()+1);
                				ruleCountVo.setCreateTime(new Date()); //当前操作时间
                				ruleCountVo.setCount(maxCount);
                				ruleCountService.updateVo(ruleCountVo);
                			}
                        	//根据ruleId，将count++
                        	ruleCountService.updateCount(ruleId);
                    	}
                    }else{//服务商信息匹配到的，新增or更新t_servicer_count数据
                    	Map<String, String> servicer_param = new HashMap<>();
                    	servicer_param.put("servicerId", servicerId);
                    	ServicerCountEntity servicerCountVo = servicerCountService.queryOneByParam(servicer_param);
            			if(servicerCountVo==null){//新增
            				ServicerCountEntity v = new ServicerCountEntity();
            				v.setDataId(UUID.randomUUID().toString().replace("-", ""));
            				v.setServicerId(servicerId);
            				v.setCount(1);
            				v.setCreateTime(new Date());
            				servicerCountService.insertVo(v);
            			}else{//修改
            				servicerCountVo.setCreateTime(new Date());
            				servicerCountService.updateVo(servicerCountVo);
            			}
                    }
            	}
            }else{
            	orderMainEntity.setChildStatus("0");
                orderMainEntity.setUpdater(RequestUtil.getLoginUser().getUserCode());
                orderMainEntity.setUpdateTime(new Date());
                orderMainEntity.setStatus("00"); //派发失败
                orderMainDao.update(orderMainEntity); // 更新服务单子状态
                //清空服务单的服务商信息
                Map<String, String> servicerMap = new HashMap<>();
                servicerMap.put("orderNo", orderMainEntity.getOrderNo());
                orderServiceProviderDao.clearInfo(servicerMap);
            	if("9999".equals(temp_code)){//超时异常
                	saveTrack(orderMainEntity.getOrderNo(), "00", "调用下游下单失败：请求超时", "01", new Date(), RequestUtil.getLoginUser());
                }else if("009".equals(temp_code)){
                	saveTrack(orderMainEntity.getOrderNo(), "00", "调用下游下单失败："+servicerName+"秘钥解析失败", "01", new Date(), RequestUtil.getLoginUser());
                }else{//失败
                	saveTrack(orderMainEntity.getOrderNo(), "00", "调用下游下单失败", "01", new Date(), RequestUtil.getLoginUser());
                }
            }
        } else {
            LoginAuthDto loginUser = RequestUtil.getLoginUser();
            saveTrack("null", "00", "下单失败，服务单不存在", "01", new Date(), loginUser);
        }
	}
	
	private void saveTrack(String orderNo, String trackType, String trackDesc, String status, Date currentDate, LoginAuthDto loginUser){
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);
        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(loginUser.getUserCode());
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(loginUser.getUserCode());
        orderTrackDao.insert(orderTrackEntity);
    }
	
}
